import bson
from fastapi import APIRouter, exceptions
from fastapi.requests import Request
from fastapi import status
from .schemas import NewTaskSchema, UpdateTaskSchema

router = APIRouter()


@router.post('/tasks/', status_code=status.HTTP_201_CREATED)
async def new_task(request: Request, task: NewTaskSchema):
    """创建新的任务"""
    coll = request.app.state.db['todo']
    task_dict = task.dict()
    result = await coll.insert_one(task_dict)  # InsertOneResult对象
    # result.inserted_id为ObjectId类型,需要转化成字符串类型才能JSON序列化
    task_dict.update({'_id': str(result.inserted_id)})
    return task_dict  # 返回新创建的task，包含_id字段


@router.get('/tasks/', status_code=status.HTTP_200_OK)
async def get_tasks(request: Request):
    """获取多条任务"""
    coll = request.app.state.db['todo']
    results = [doc async for doc in coll.find({})]
    for result in results:
        result['_id'] = str(result['_id'])
    return results


@router.get('/tasks/{task_id}/', status_code=status.HTTP_200_OK)
async def get_task(request: Request, task_id: str):
    """获取单条任务"""
    coll = request.app.state.db['todo']
    try:
        result = await coll.find_one({'_id': bson.ObjectId(task_id)})
    except bson.errors.InvalidId:
        raise exceptions.HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail='无效ID'
        )
    else:
        # 路径参数中的ID有效，但是对应的文档可能不存在同样抛404错误
        if result is None:
            raise exceptions.HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail='任务不存在'
            )
        result['_id'] = str(result['_id'])
        return result


@router.put('/tasks/{task_id}/', status_code=status.HTTP_200_OK)
async def update_task(request: Request, task_id: str, task: UpdateTaskSchema):
    """更新任务"""
    coll = request.app.state.db['todo']
    try:
        result = await coll.find_one_and_update(
            {'_id': bson.ObjectId(task_id)},
            {'$set': task.dict()}
        )
    except bson.errors.InvalidId:
        raise exceptions.HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail='无效ID'
        )
    else:
        # 路径参数中的ID有效，但是对应的文档可能不存在同样抛404错误
        if result is None:
            raise exceptions.HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail='任务不存在'
            )
        result['_id'] = str(result['_id'])
        return result


@router.delete('/tasks/{task_id}/', status_code=status.HTTP_200_OK)
async def delete_task(request: Request, task_id: str):
    """删除任务"""
    coll = request.app.state.db['todo']
    try:
        result = await coll.find_one_and_delete(
            {'_id': bson.ObjectId(task_id)}
        )
    except bson.errors.InvalidId:
        raise exceptions.HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail='无效ID'
        )
    else:
        # 路径参数中的ID有效，但是对应的文档可能不存在同样抛404错误
        if result is None:
            raise exceptions.HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail='任务不存在'
            )
        result['_id'] = str(result['_id'])
        return result
